#include "curl_download_tool.h"

#include <QDebug>

class CurlDownloadToolPrivate
{
public:
    CurlDownloadToolPrivate();
    ~CurlDownloadToolPrivate();

    bool download(int &statusCode, const std::string &url, const std::string &filePath, const std::string &md5 = "");
    uint64_t getDownloadFileSize(const std::string &url);

    bool m_enableBrokenDownload;
    bool m_enableSpeedLimitDownload;
    int m_speedLimit;
    std::string m_caCertFile;
    std::string m_localCertFile;
    std::string m_privateKeyFile;

private:
    std::map<std::string, std::string> parseHttpHeader(std::string &header);
};

CurlDownloadToolPrivate::CurlDownloadToolPrivate()
    : m_enableBrokenDownload(false)
    , m_enableSpeedLimitDownload(false)
    , m_speedLimit(100)
{
}

CurlDownloadToolPrivate::~CurlDownloadToolPrivate()
{
}

bool CurlDownloadToolPrivate::download(int &statusCode, const std::string &url, const std::string &filePath, const std::string &md5)
{
    // 获取文件信息失败
    // if (getDownloadFileSize(url) == -1) {
    //     return false;
    // }

    if (!(url.length() && filePath.length())) {
        return false;
    }

    std::string cmd = "curl -i --create-dirs";
    if (m_caCertFile.length()) {
        cmd += " --cacert " + m_caCertFile;
    }
    if (m_localCertFile.length()) {
        cmd += " --cert " + m_localCertFile;
    }
    if (m_privateKeyFile.length()) {
        cmd += " --key " + m_privateKeyFile;
    }

    if (m_enableSpeedLimitDownload) {
        // 单次下载的数据大小,单位是字节
        cmd += " --limit-rate " + std::to_string(m_speedLimit) + "k";
    }

    if (m_enableBrokenDownload) {
        cmd += " -C -";
    }

    cmd += " --url '" + url + "' -o '" + filePath + "' --get";

    qInfo() << cmd.c_str();
    int code = system(cmd.c_str()) >> 8;
    /**
     * 7     网络不通
     * 23    无法创建文件
     */
    qInfo() << code;
    return code == 0;
}

uint64_t CurlDownloadToolPrivate::getDownloadFileSize(const std::string &url)
{
    if (url.length() == 0) {
        return -1;
    }

    std::string cmd = "curl -i";
    if (m_caCertFile.length()) {
        cmd += " --cacert " + m_caCertFile;
    }
    if (m_localCertFile.length()) {
        cmd += " --cert " + m_localCertFile;
    }
    if (m_privateKeyFile.length()) {
        cmd += " --key " + m_privateKeyFile;
    }

    cmd += " --url '" + url + "'";

    qInfo() << cmd.c_str();
    FILE *lsofFile_p = popen(cmd.c_str(), "r");

    if (!lsofFile_p) {
        return -1;
    }

    char buffer[1024];
    char *line_p = fgets(buffer, sizeof(buffer), lsofFile_p);
    pclose(lsofFile_p);

    qInfo() << buffer;
    return -1;
}
std::map<std::string, std::string> CurlDownloadToolPrivate::parseHttpHeader(std::string &header)
{
    return std::map<std::string, std::string>();
}

CurlDownloadTool::CurlDownloadTool()
    : m_private(new CurlDownloadToolPrivate)
{
}

CurlDownloadTool::~CurlDownloadTool()
{
    delete m_private;
}

// 断点续传
bool CurlDownloadTool::enableBrokenDownload()
{
    return m_private->m_enableBrokenDownload;
}

void CurlDownloadTool::setBrokenDownload(bool enable)
{
    m_private->m_enableBrokenDownload = enable;
}

// 限速下载
bool CurlDownloadTool::enableSpeedLimitDownload()
{
    return m_private->m_enableSpeedLimitDownload;
}

void CurlDownloadTool::setSpeedLimitDownload(bool enable)
{
    m_private->m_enableSpeedLimitDownload = enable;
}

int CurlDownloadTool::speedLimitValue()
{
    return m_private->m_speedLimit;
}

void CurlDownloadTool::setSpeedLimitValue(int value)
{
    if (value < 0) {
        return;
    }

    m_private->m_speedLimit = value;
}

// ssl配置
void CurlDownloadTool::setSSLConfiguration(const std::string &caCertFile, const std::string &localCertFile, const std::string &privateKeyFile)
{
    m_private->m_caCertFile = caCertFile;
    m_private->m_localCertFile = localCertFile;
    m_private->m_privateKeyFile = privateKeyFile;
}

// 同步下载
bool CurlDownloadTool::download(int &statusCode, const std::string &url, const std::string &filePath, const std::string &md5)
{
    return m_private->download(statusCode, url, filePath, md5);
}

// 异步下载
void CurlDownloadTool::download(DownloadCallBackFunction cbFun, const std::string &url, const std::string &filePath, const std::string &md5)
{
}

uint64_t CurlDownloadTool::getDownloadFileSize(const std::string &url)
{
    return m_private->getDownloadFileSize(url);
}